package org.flexharmony;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;


/**
 * Allows fine grained control over how Java class fields get generated into
 * ActionScript fields. If a class is annotated with @ASClass(syncAllFields=false)
 * then only only fields with this annotation will be included in the ActionScript
 * transformation.
 * 
 * @author Corey Baswell
 */
@Target({ElementType.FIELD})
@Retention(value=RetentionPolicy.CLASS)
public @interface ASField
{
  /**
   * The ActionScript type a Java field will get transformed into to. If set to
   * {@link ASFieldType#NULL} then the following default Java to ActionScript 
   * transformations will be used:
   * 
   * <table cellspacing="10" cellpadding="5">
   *  <tr><th align="center">Java Type</th><th align="center">ActionScript Type</th></tr>
   *  <tr><td align="center">java.lang.String</td><td align="center">String</td></tr>
   *  <tr><td align="center">char</td><td align="center">String</td></tr>
   *  <tr><td align="center">char[]</td><td align="center">String</td></tr>
   *  <tr><td align="center">java.lang.Character</td><td align="center">String</td></tr>
   *  <tr><td align="center">java.lang.Character[]</td><td align="center">String</td></tr>
   *  <tr><td align="center">java.math.BigInteger</td><td align="center">String</td></tr>
   *  <tr><td align="center">java.math.BigDecimal</td><td align="center">String</td></tr>
   *  
   *  <tr><td align="center">byte</td><td align="center">Number</td></tr>
   *  <tr><td align="center">java.lang.Byte</td><td align="center">Number</td></tr>
   *  <tr><td align="center">short</td><td align="center">Number</td></tr>
   *  <tr><td align="center">java.lang.Short</td><td align="center">Number</td></tr>
   *  <tr><td align="center">int</td><td align="center">Number</td></tr>
   *  <tr><td align="center">java.lang.Integer</td><td align="center">Number</td></tr>
   *  <tr><td align="center">float</td><td align="center">Number</td></tr>
   *  <tr><td align="center">java.lang.Float</td><td align="center">Number</td></tr>
   *  <tr><td align="center">double</td><td align="center">Number</td></tr>
   *  <tr><td align="center">java.lang.Double</td><td align="center">Number</td></tr>

   *  <tr><td align="center">byte[]</td><td align="center">flash.utils.ByteArray</td></tr>
   *  <tr><td align="center">java.lang.Byte[]</td><td align="center">flash.utils.ByteArray</td></tr>

   *  <tr><td align="center">java.util.Date</td><td align="center">Date</td></tr>
   *  <tr><td align="center">java.util.GregorianCalendar</td><td align="center">Date</td></tr>
   *  
   *  <tr><td align="center">any array type not listed</td><td align="center">Array</td></tr>
   *  
   *  <tr><td align="center">java.util.ArrayCollection</td><td align="center">mx.collections.ArrayCollection</td></tr>
   *  <tr><td align="center">java.util.ConcurrentLinkedQueue</td><td align="center">mx.collections.ArrayCollection</td></tr>
   *  <tr><td align="center">java.util.CopyOnWriteArraySet</td><td align="center">mx.collections.ArrayCollection</td></tr>
   *  <tr><td align="center">java.util.EnumSet</td><td align="center">mx.collections.ArrayCollection</td></tr>
   *  <tr><td align="center">java.util.HashSet</td><td align="center">mx.collections.ArrayCollection</td></tr>
   *  <tr><td align="center">java.util.LinkedBlockingQueue</td><td align="center">mx.collections.ArrayCollection</td></tr>
   *  <tr><td align="center">java.util.LinkedHashSet</td><td align="center">mx.collections.ArrayCollection</td></tr>
   *  <tr><td align="center">java.util.LinkedList</td><td align="center">mx.collections.ArrayCollection</td></tr>
   *  <tr><td align="center">java.util.PriorityBlockingQueue</td><td align="center">mx.collections.ArrayCollection</td></tr>
   *  <tr><td align="center">java.util.PriorityQueue</td><td align="center">mx.collections.ArrayCollection</td></tr>
   *  <tr><td align="center">java.util.Stack</td><td align="center">mx.collections.ArrayCollection</td></tr>
   *  <tr><td align="center">java.util.SynchronousQueue</td><td align="center">mx.collections.ArrayCollection</td></tr>
   *  <tr><td align="center">java.util.TreeSet</td><td align="center">mx.collections.ArrayCollection</td></tr>
   *  <tr><td align="center">java.util.Vector</td><td align="center">mx.collections.ArrayCollection</td></tr>
   *  
   *  
   * <tr><td align="center">java.util.Attributes</td><td align="center">Object</td></tr>
   * <tr><td align="center">java.util.ConcurrentHashMap</td><td align="center">Object</td></tr>
   * <tr><td align="center">java.util.ConcurrentSkipListMap</td><td align="center">Object</td></tr>
   * <tr><td align="center">java.util.Dictionary</td><td align="center">Object</td></tr>
   * <tr><td align="center">java.util.EnumMap</td><td align="center">Object</td></tr>
   * <tr><td align="center">java.util.HashMap</td><td align="center">Object</td></tr>
   * <tr><td align="center">java.util.Hashtable</td><td align="center">Object</td></tr>
   * <tr><td align="center">java.util.IdentityHashMap</td><td align="center">Object</td></tr>
   * <tr><td align="center">java.lang.Object</td><td align="center">Object</td></tr>
   * <tr><td align="center">java.util.Properties</td><td align="center">Object</td></tr>
   * <tr><td align="center">java.util.TreeMap</td><td align="center">Object</td></tr>
   * <tr><td align="center">java.util.WeakHashMap</td><td align="center">Object</td></tr>
   * 
   * </table>
   * 
   * <br>
   * If the Java type is one not in this list then it will be assumed to be a custom type an carried over directly
   * in the generated ActionScript code.
   */
  ASFieldType type() default ASFieldType.NULL;
  
  /**
   * The visibility (default, private, protected, or public) of the generated 
   * ActionScript field. If set to {@link ASVisiblity#NULL} the following
   * transformation rules will be used to determine the visibility for non-static
   * fields.
   * 
   * <ol>
   * <li>If {@link #access()} is {@link ASAcces#NULL} or {@link ASAcces#PROPERTY} 
   * the visibility will be set to private</li>
   * <li>If {@link #access()} is set to {@link ASAcces#FIELD} the visibility will be set to public.</li>
   * </ol>
   * 
   * Static fields generated in ActionScript will have the same visibility as the
   * Java source field.
   */
  ASVisiblity visibility() default ASVisiblity.NULL;

  /**
   * The access of the generate ActionScript field (either direct field access or through a property).
   * If set to {@link ASAcces#NULL} the following transformation rules will be used to
   * determine the access for non-static fields.
   * 
   * <ol>
   * <li>If {@link #visibility()} is {@link ASVisiblity#NULL} or {@link ASVisiblity#PRIVATE}
   * a public property get and set function will be generated for this field.</li>
   * <li>If {@link #visibility()} is {@link ASVisiblity#DEFAULT}, {@link ASVisiblity#PROTECTED},
   * or {@link ASVisiblity#PUBLIC} only a field will generated.</li>
   * </ol>
   * 
   * Static fields generated in ActionScript will never have properties generated by default.
   */
  ASAcces access() default ASAcces.NULL;

  /**
   * The initialization for generated ActionScript fields. Default Java values will
   * only be carried over for int, Integer, float, Float, long, Long, double, Double,
   * or String. Any other initialization generated in ActionScript needs to be explicitly
   * specified using this property.
   */
  String initialization() default "";
}
